package wzh000;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import wzh000.common.Rsp;

public class Client {
	private String host;
	private int serverPort = 42083;
	private Calendar cal;
	private SimpleDateFormat date_format;
	private Socket skt;
	private boolean hasImage;
	private double CC;
	private BufferedImage img;
	private String reqTime;
	private ArrayList<ServerInfo> serverList;

	public Client() {

		this.serverList = new ArrayList<ServerInfo>();
	}

	public Client(String host, int port) {
		this.host = host;
		this.serverPort = port;
		this.cal = new GregorianCalendar(2004, 01, 01, 00, 00);
		this.date_format = new SimpleDateFormat("yyyyMMddHHmm");

		try {
			this.skt = new Socket(this.host, this.serverPort);
		} catch (UnknownHostException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}
	}

	public String getReqTime() {
		return this.reqTime;
	}

	private void setReqTime(String req) {
		this.reqTime = req;
	}

	public boolean hasImage() {
		return this.hasImage;
	}

	public int getPort() {
		return this.serverPort;
	}

	public String getHost() {
		return this.host;
	}

	private void setHasImage(boolean b) {
		this.hasImage = b;
	}

	public Rsp sendReq(int i, String ip, String host) {
		 String time = generateTime(i);
		//String time = String.format("%03d", i);
		// String time = "200806132200";
		PrintWriter out = null;
		InputStream in;
		Rsp o = null;
		ObjectInputStream ois = null;

		try {
			//this.skt = new Socket("127.0.0.1", 42083);
			 //System.out.println()
			 this.skt = new Socket(ip, 42083);
		} catch (UnknownHostException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		} finally{
                        if(this.skt == null){
                                return o;
                        }

                }

		try {
			
			setReqTime(time);
			out = new PrintWriter(this.skt.getOutputStream(), true);
			in = this.skt.getInputStream();
			
			System.out.println("Requesting time:" + time + ", ServerTile: " + host);
			out.println(time);
			out.flush();

			ois = new ObjectInputStream(in);
			o = (Rsp) ois.readObject();

			/*
			 * BufferedImage image = null; if(o.getResult() == true){
			 * System.out.println("Cloudiness: " + o.getCC()); setCC(o.getCC());
			 * image = ImageIO.read(this.skt.getInputStream()); }else{ //close
			 * socket //connet another front-server } if(image != null){
			 * setHasImage(true); setImg(image); } /* double cc =
			 * ois.readDouble(); setCC(cc); System.out.println("Received CC is "
			 * + cc);
			 * 
			 * BufferedOutputStream bos = new BufferedOutputStream( new
			 * FileOutputStream("zw.jpg")); InputStream inputStream =
			 * this.skt.getInputStream(); BufferedInputStream bis = new
			 * BufferedInputStream(inputStream); byte[] content = new
			 * byte[1024]; int r; int bytesRead = 0; while ((r =
			 * bis.read(content)) != -1) { bos.write(content, 0, r); bytesRead
			 * += r; } if (content[0] == '0') { setHasImage(false); }
			 * 
			 * System.out.println("received " + bytesRead + " bytes");
			 * 
			 * out.close(); ois.close(); bos.close(); inputStream.close();
			 * bis.close();
			 */
			// skt.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			/*
			 * try { if (this.skt != null) { this.skt.close(); } } catch
			 * (IOException e) { e.printStackTrace(); }
			 */

		}
		return o;
	}

	private int randBetween(int start, int end) {
		return start + (int) Math.round(Math.random() * (end - start));
	}

	public String generateTime(int t) {

		String req = null;
		String date;
		

		int year = randBetween(2008, 2008);// Here you can set Range of years
											// you need
		date = String.format("%04d", year);
		req = date;
		int month = randBetween(0, 6);
		date = String.format("%02d", month);
		req += date;
		GregorianCalendar gc = new GregorianCalendar(year, month, 1);
		int day = randBetween(1, gc.getActualMaximum(Calendar.DAY_OF_MONTH));
		date = String.format("%02d", day);
		req += date;
		int hour = randBetween(9, 22); // Hours will be displayed in between 9
										// to 22
		date = String.format("%02d", hour);
		req += date;
		int min = randBetween(0, 59);
		date = String.format("%02d", min);
		req += date;
		System.out.println(req);

		// int sec = randBetween(0, 59);
		return req;

		/*
		 * 
		 * gc.set(year, month, day, hour, min);
		 * 
		 * Date a = gc.getTime(); System.out.println(gc.get(Calendar.MONTH));
		 * 
		 * System.out.println(dfDateTime.format(gc.getTime()));
		 * 
		 * //this.cal.roll(Calendar.MINUTE, t);
		 * 
		 * //return (this.date_format.format(this.cal.getTime()));
		 * 
		 * String date2 = String.format("%02d", t);
		 * 
		 * return "201006" + date2 + "2000";
		 */
	}

	public void close() {
		try {
			if (this.skt != null) {
				this.skt.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public double getCC() {
		return this.CC;
	}

	private void setCC(double in) {
		this.CC = in;
	}

	private void setImg(BufferedImage img) {
		this.img = img;
	}

	public BufferedImage getImg() {
		return this.img;
	}

	public void addServer(ServerInfo server) {
		this.serverList.add(server);
	}

	public ServerInfo getServer(int i) {
		return this.serverList.get(i);
	}

	public void getImage(Rsp o) {
		BufferedImage image = null;

		System.out.println("Cloudiness: " + o.getCC());
		setCC(o.getCC());
		try {
			image = ImageIO.read(this.skt.getInputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (image != null) {
			setHasImage(true);
			setImg(image);
		}
		try {
			this.skt.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */

	public static void main(String[] args) {

		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (InstantiationException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (UnsupportedLookAndFeelException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		JFrame frame = new JFrame();
		JPanel panel = null;
		JLabel label = new JLabel();
		JLabel label_img = new JLabel();
		Client client = new Client();
		// client.generateTime(1);
		ImageIcon ico = new ImageIcon();
		Container c = frame.getContentPane();
		c.setLayout(new BorderLayout());

		c.add(label, BorderLayout.PAGE_START);
		c.add(label_img, BorderLayout.CENTER);
		//c.add(label_img, BorderLayout.PAGE_END);
		//frame.getContentPane().add(label);

		/*
		 * try{ panel = new ImageDisplayer(); }catch(Exception ex){
		 * ex.printStackTrace(); }
		 */
		int j;
		for (j = 0; j < 3; j++) {
			InetAddress address = null;
			String myAddress = null;
			try {
				address = InetAddress.getByName(args[j]);
				myAddress = InetAddress.getLocalHost().getHostAddress();
			} catch (UnknownHostException e) {
				e.printStackTrace();
				System.exit(2);
			}

			System.out.println(address.getHostName() + "="
					+ address.getHostAddress());
			System.out.println("myIP=" + myAddress);
			if (myAddress.equals(address.getHostAddress())) {
				System.exit(0);
			}
			String ip = new String();
			ip = address.getHostAddress();
			ServerInfo server = new ServerInfo(args[j], ip);
			
			client.addServer(server);

		}

		for (j = 0; j < 3; j++) {
			ServerInfo serverIP = client.getServer(j);
			System.out.println(serverIP.getHostName());
		}
		// String ip = args[0];
		int i = 0;
		int k = 0;
		// Rectangle r = frame.getBounds();
		// int h = r.height;
		// int w = r.width;

		label.setPreferredSize(new Dimension(1024, 50));
		label.setMinimumSize(new Dimension(1024, 50));
		label_img.setPreferredSize(new Dimension(704, 576));
		label_img.setMinimumSize(new Dimension(704, 576));
		label.setFont(label.getFont().deriveFont(30.0f));
		label_img.setFont(label_img.getFont().deriveFont(30.0f));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// frame.setSize(w, h);
		while (true) {
			for (; i < 90; i++) {
				long t1 = System.currentTimeMillis();
				// Client client = new Client("127.0.0.1", 42083);
				Rsp result = null;
				do {
					System.out.println("k=" + k);
					result = client.sendReq(i, client.getServer(k).getIP(),
							client.getServer(k).getHostName());
					if (result == null) {
						k++;
					}
					if (k == 3) {
						k = 0;
					}

				} while (result==null);

				client.getImage(result);

				/*
				 * try { Thread.sleep(1000); } catch (InterruptedException e) {
				 * 
				 * e.printStackTrace(); }
				 */
				// frame.setResizable(false);
				if (client.hasImage() == true) {
					ico.setImage(client.getImg());
					label_img.setIcon(ico);
					label_img.setHorizontalTextPosition(JLabel.CENTER);
					//label_img.setVerticalTextPosition(JLabel.TOP);

				}

				String str = String.format("%.1f%%", client.getCC());
				long t = System.currentTimeMillis() - t1;
				
				label.setText("Time: " + client.getReqTime()
						+ ", Cloudiness: " + str + " TimeSpent: " + t);
				// frame.setTitle("RequestTime: "+ client.getReqTime() +
				// ", Cloudiness: " + Double.toString(client.getCC()));

				System.out.format("CC: %.1f%%", client.getCC());
				// frame.setVisible(false);
                                //frame.setBounds(0,0, 1024, 768);
				//frame.setSize(1024, label.getHeight());
                                frame.pack();

				frame.setVisible(true);
				// frame.setLocationRelativeTo(null);
				
				// frame.validate();
				// frame.repaint();
				// GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(frame);
				// client.generateTime(15);
				client.close();
			}

			i = 0;

		}

	}

}
